/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.folha.controller;

import br.com.folha.dao.CalculoFolhaDao;
import br.com.folha.dao.DiaSemanaDao;
import br.com.folha.dao.DisciplinaDao;
import br.com.folha.dao.DisponibilidadeDao;
import br.com.folha.dao.GenericoDao;
import br.com.folha.dao.GradeDao;
import br.com.folha.dao.ProfessorDao;
import br.com.folha.dao.SalaDao;
import br.com.folha.dao.TurmaDao;
import br.com.folha.dao.UnidadeDao;
import br.com.folha.entity.Disciplina;
import br.com.folha.entity.DisponibilidadeProfessor;
import br.com.folha.entity.GradeHoraria;
import br.com.folha.entity.GradeHorariaFp;
import br.com.folha.entity.Professor;
import br.com.folha.entity.Sala;
import br.com.folha.entity.Turma;
import br.com.folha.entity.TurmaAula;
import br.com.folha.entity.Unidade;
import br.com.folha.service.FolhaService;
import br.com.folha.service.GradeService;
import br.com.folha.service.TurmaService;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.view.JasperViewer;

/**
 *
 * @author marceloml
 */
@ManagedBean(name = "GradeController")
@ViewScoped
public final class GradeController implements Serializable{
    
    private static final long serialVersionUID = 1L;
    
    private Unidade unidade;
    private Integer selectedUnidades;
    private UnidadeDao unidadeDao = new UnidadeDao();
    private GenericoDao gradeDao = new GenericoDao();
    
    private Date data = new Date();
    
    private GradeHoraria gradeHoraria;
    private GradeHoraria gradeHorariaSelecionada;
    private TurmaDao turmaDao = new TurmaDao();
    private ProfessorDao professorDao = new ProfessorDao();
    private DisciplinaDao disciplinaDao = new DisciplinaDao();    
    private DiaSemanaDao diaSemanaDao   = new DiaSemanaDao();
    private boolean retorno;
    private Date dataInicial;
    private Date dataFinal;
    
    private GradeService grade = new GradeService();    
    private List<GradeHoraria> retornoGrade;
    private Unidade unidadeCorrente;
    private String nomeUnidade;
    private GradeDao consulta = new GradeDao();

    private List<Disciplina> listaProfessores;
    private Integer selectedDisciplina;
    private Disciplina disciplina;      
    
    private Integer selectedProfessor;    
    private List<Object> professoresAtivos;
    
    private Turma turma;
    
    private transient DataModel lista;
    private Set<Unidade> unidadeUsuario;
    
    private Integer selectedTurma;
    
    private String horaIni;
    private String horaFim;    
    private String dataAula;
    
    private String acao;
    private Date tmpHoraFim;
    private boolean validaHoraFim;
    private Date dataCalculada;    
    private boolean comparaData;
    private int diaAtual;
    private List<GradeHoraria> retornoGradeSemanaSeguinte;
    
    private Integer filtroSelecionado;
    private Boolean exibeDatas;
    private String dataIniFiltro;
    private String dataFimFiltro;
    
    private Date dataAulaComparacao;
    private Date dataAtualComparacao;
    private List<DisponibilidadeProfessor> retornoLista;
    
    private transient DataModel listaSala;
    private SalaDao salaDao = new SalaDao();
    private Sala sala;
    private Integer selectedSala;
    
    private String selectedMaterial;
    private GradeHorariaFp folhaPagamento;
    
    private TurmaService turmaService = new TurmaService();
    private Integer tipoContrato;
    private boolean teste;
    
    private CalculoFolhaDao calculoDao = new CalculoFolhaDao();
    
    public GradeController(){
        
        gradeHoraria = new GradeHoraria(); 
        folhaPagamento = new GradeHorariaFp();
        selectedUnidades = 0;
        filtroSelecionado = 0;
        acao = "";
        getExibeDatas();
        
    }        
    
    /*
     * Função utilizada pelo filtro por datas
     * onde é realizada a consulta das aulas da grade com os filtros passados pelo usuário
     * data inicial e data final
     */
    public void atualizaLista() {                  
      
      if(filtroSelecionado == 1 && dataIniFiltro != null && !dataIniFiltro.equals("")){
        Calendar calendar = Calendar.getInstance(); // ou new GregorianCalendar  
        calendar.clear();  
        calendar.set(Calendar.YEAR,Integer.parseInt(this.dataIniFiltro.substring(6, 10)));
        calendar.set(Calendar.MONTH, Integer.parseInt(this.dataIniFiltro.substring(3, 5)) - 1);
        calendar.set(Calendar.DAY_OF_MONTH,Integer.parseInt(this.dataIniFiltro.substring(0, 2)));
        
        Calendar calendar2 = Calendar.getInstance(); // ou new GregorianCalendar  
        calendar2.clear();  
        calendar2.set(Calendar.YEAR,Integer.parseInt(this.dataFimFiltro.substring(6, 10)));
        calendar2.set(Calendar.MONTH, Integer.parseInt(this.dataFimFiltro.substring(3, 5)) - 1);
        calendar2.set(Calendar.DAY_OF_MONTH,Integer.parseInt(this.dataFimFiltro.substring(0, 2)));                  
        
        if(lista == null){
        
            lista = new ListDataModel(consulta.consultaGrade(unidadeDao.getById(selectedUnidades),calendar.getTime(), calendar2.getTime()));
        
        }
      }

    }    
    
    public Collection<SelectItem>  getCarregarUnidade(){                
        
        unidade = new Unidade();        
        LoginController usuarioLogado = new LoginController();        
        Collection<SelectItem> lst = new ArrayList<SelectItem>(); 
        lst.add(new SelectItem(null, "Selecione a Unidade"));      //Primeiro item do select 
        
        unidadeUsuario = usuarioLogado.Usuario.getUnidades();                
        
        for (Iterator iterator = usuarioLogado.Usuario.getUnidades().iterator(); iterator.hasNext();){            
            Unidade unidade = (Unidade) iterator.next();             
            if(unidade.getId().equals(selectedUnidades)){
                lst.add(new SelectItem(unidade.getId(), unidade.getNome()));                          
            }
            
        }                
        
        return lst;                  
        
    }

    
    /*
     * Momento que é carregado o select com as unidades que o usuário logado pertence
     * para que o mesmo selecione de qual unidade deseja que a grade horária seja exibida
     */    
    public Collection<SelectItem>  getCarregarUnidadeDisponivel(){
        
        unidade = new Unidade();        
        LoginController usuarioLogado = new LoginController();        
        Collection<SelectItem> lst = new ArrayList<SelectItem>(); 
        lst.add(new SelectItem(null, "Selecione a Unidade"));      //Primeiro item do select 
        
        unidadeUsuario = usuarioLogado.Usuario.getUnidades();                
        
        for (Iterator iterator = usuarioLogado.Usuario.getUnidades().iterator(); iterator.hasNext();){            
            Unidade unidade = (Unidade) iterator.next();             
            
                lst.add(new SelectItem(unidade.getId(), unidade.getNome()));                                      
            
        }                
        
        return lst;                  
        
    } 
    
    public Collection<SelectItem>  getCarregarTurma(){
        
        turma = new Turma();        
        LoginController usuarioLogado = new LoginController();        
        Collection<SelectItem> lst = new ArrayList<SelectItem>(); 
        lst.add(new SelectItem(null, "Selecione a Turma"));      //Primeiro item do select 
        
        unidadeUsuario = usuarioLogado.Usuario.getUnidades();                
        
        for (Iterator iterator = turmaDao.listaTurmaUnidade(selectedUnidades).iterator(); iterator.hasNext();){            
            Turma retornoTurma = (Turma) iterator.next();             
            
                lst.add(new SelectItem(retornoTurma.getId(), retornoTurma.getNome()));                                      
            
        }                
        
        return lst;                  
        
    }    
    
    /*
     * Método utilizado para verificar se já existe grade gerada para a semana atual,
     * caso não exista é perguntado ao usuário se deseja gerá-la
     */
    public void existeGrade(){                
        
        Calendar calendar = Calendar.getInstance(); // ou new GregorianCalendar  
        calendar.clear();  
        calendar.setTime(data);         
        
        dataInicial = grade.calculaDataAnterior(data, 1);
        dataFinal   = grade.calculaData(data, 7);          
        
        retornoGrade = consulta.consultaGrade(unidadeDao.getById(selectedUnidades),dataInicial, dataFinal);
        
        diaAtual = calendar.get(Calendar.DAY_OF_WEEK);
        
        /*
         * Verifica se existe grade horária gerada do dia atual até o próxima sábado,
         * caso não existe pergunta ao usuário se deseja gerá-la
         */
        if(retornoGrade.isEmpty()){
            org.primefaces.context.RequestContext.getCurrentInstance().execute("geraGrade.show();");  
        }
        
        /*
         * Caso seja verificado que o dia atual é uma sexta ou sábado, é perguntado ao usuário
         * se deseja gerar a grade para a próxima semana, caso ainda não tenha sido gerada
         */        
        if(diaAtual == 6 || diaAtual == 7){
            
            dataInicial = grade.calculaData(data, 1);
            dataFinal   = grade.calculaData(dataInicial, 7);            
            
            retornoGradeSemanaSeguinte = consulta.consultaGrade(unidadeDao.getById(selectedUnidades),dataInicial, dataFinal);            
            
                if(retornoGradeSemanaSeguinte.isEmpty()){
                   org.primefaces.context.RequestContext.getCurrentInstance().execute("confirmationGeraGrade.show();");  
                }        
        }
        unidadeCorrente = unidadeDao.getById(selectedUnidades);
        setNomeUnidade(unidadeCorrente.getNome());
        
    }
    
    /*
     * Método utilizado para gerar grade horária para a semana atual
     */
    public void incluirSemanaAtual(){
        
        List<Turma> listaSemanaAtual = turmaDao.listaTurmaUnidade(selectedUnidades);
        FacesMessage msg = null;        
        LoginController usuarioLogado = new LoginController();                
        
        try{
                
                 Calendar calendar = Calendar.getInstance(); // ou new GregorianCalendar  
                 calendar.clear();  
                 calendar.setTime(data);            
            
            for (int i = 0; i < listaSemanaAtual.size(); i++) {            

                 List<TurmaAula> listaAula = turmaDao.listaTurmaAula(listaSemanaAtual.get(i).getId());                   
                 
                 for(int j = 0; j < listaAula.size(); j++) { 
                     
                    tmpHoraFim = listaAula.get(j).getHoraFim();
                    
                    validaHoraFim = Integer.parseInt(String.valueOf(tmpHoraFim).substring(0, 2)+String.valueOf(tmpHoraFim).substring(3, 5)) >= calendar.get(Calendar.HOUR_OF_DAY)+calendar.get(Calendar.MINUTE);

                    dataCalculada  = grade.calculaData(data, listaAula.get(j).getDiaSemana().getId());
                    
                    if(calendar.get(Calendar.DAY_OF_WEEK) <=  listaAula.get(j).getDiaSemana().getId()){
                    
                            if(grade.validaGrade(dataCalculada, data, listaAula.get(j).getHoraFim())){
                                DisponibilidadeDao disponibilidadeDao = new DisponibilidadeDao();
                                
                                /*
                                 * Valida se o professor está disponivel no horário informado
                                 */                                
                                System.out.println("O Professor : "+listaAula.get(j).getProfessor().getNome());
                                retornoLista = disponibilidadeDao.consultaDisponibilidadeProfessor(listaAula.get(j).getProfessor(), listaAula.get(j).getDiaSemana(), listaAula.get(j).getHoraIni(), listaAula.get(j).getHoraFim());                                                                
                                
                                if(retornoLista.isEmpty()){
                                    System.out.println("Não está disponivel no dia e horários a seguir");
                                }else{
                                    System.out.println("Estará disponivel no dia e horários a seguir");
                                }                                                                
                                
                                   gradeHoraria.setTurma(turmaDao.getById(listaSemanaAtual.get(i).getId()));                    
                                   gradeHoraria.setDisciplina(listaAula.get(j).getDisciplina());
                                   gradeHoraria.setProfessor(listaAula.get(j).getProfessor());
                                   gradeHoraria.setUnidade(unidadeDao.getById(selectedUnidades));
                                   gradeHoraria.setHoraIni(listaAula.get(j).getHoraIni());
                                   gradeHoraria.setHoraFim(listaAula.get(j).getHoraFim());
                                   gradeHoraria.setTipoContrato(listaAula.get(j).getTipoContrato());
                                   gradeHoraria.setSala(salaDao.getById(listaAula.get(j).getSala().getId()));
                                   gradeHoraria.setMaterial(listaAula.get(j).getMaterial());
                                   gradeHoraria.setData(grade.calculaData(data, listaAula.get(j).getDiaSemana().getId()));
                                   gradeHoraria.setDt_cadastro(data);
                                   gradeHoraria.setUsuario_cadastro(usuarioLogado.getUsuario().getId());                                                                      
                                   
                                   retorno = gradeDao.salvar(gradeHoraria); 
                                   
                                    SimpleDateFormat hr = new SimpleDateFormat("HH:mm");   
                                    String pattern = "HH:mm";  

                                    DateFormat df = new SimpleDateFormat(pattern); 
                                    
                                    Integer idGrade;
                                    idGrade = consulta.buscaUltRegistro();                                                                           
                                       
                                   folhaPagamento.setId_grade(idGrade);                                    
                                   
                                   folhaPagamento.setTurma(turmaDao.getById(listaSemanaAtual.get(i).getId()));                    
                                   folhaPagamento.setDisciplina(listaAula.get(j).getDisciplina());
                                   folhaPagamento.setProfessor(listaAula.get(j).getProfessor());
                                   folhaPagamento.setUnidade(unidadeDao.getById(selectedUnidades));
                                   folhaPagamento.setHoraIni(listaAula.get(j).getHoraIni());
                                   folhaPagamento.setHoraIniOri(listaAula.get(j).getHoraIni());
                                   folhaPagamento.setHoraFimOri(listaAula.get(j).getHoraFim());
                                   folhaPagamento.setHoraFim(listaAula.get(j).getHoraFim());
                                   folhaPagamento.setAtraso(df.parse("00:00"));
                                                                
                                    calendar.clear();  
                                    calendar.setTime(grade.calculaData(data, listaAula.get(j).getDiaSemana().getId()));
                                   
                                    tipoContrato = turmaService.buscaTipoContrato(professorDao.getById(selectedProfessor), diaSemanaDao.getById(calendar.get(Calendar.DAY_OF_WEEK)), listaAula.get(j).getHoraIni(), listaAula.get(j).getHoraFim());

                                    folhaPagamento.setTipoContrato(tipoContrato);                                                                      
                                   
                                   folhaPagamento.setData(gradeHoraria.getData());
                                   folhaPagamento.setDt_atualizacao(data);
                                   folhaPagamento.setUsuario_atualizacao(usuarioLogado.getUsuario().getId()); 
                                    
                                    Date horaIniNova = df.parse(df.format(folhaPagamento.getHoraIni()));
                                    Date horaFimNova = df.parse(df.format(folhaPagamento.getHoraFim()));

                                    Float valor = 0F;
                                    FolhaService folhaService = new FolhaService();
                                    valor = folhaService.getValor(listaAula.get(j).getProfessor(), unidadeDao.getById(selectedUnidades), turmaDao.getById(selectedTurma), hr.parse(hr.format(horaIniNova)), hr.parse(hr.format(horaFimNova)));
                                    
                                    folhaPagamento.setValor(BigDecimal.valueOf(valor));
                                   
                                   gradeDao.salvar(folhaPagamento);                                                                  

                           }
                     
                    }

                 }

            }

            
            getLista();
                        dataInicial = grade.calculaData(data, calendar.get(Calendar.DAY_OF_WEEK));
                        dataFinal   = grade.calculaData(data, 7);
                        
                        SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy"); 
                                
                        msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Grade Horária Gerada para o Período de "+formato.format(dataInicial)+" até "+formato.format(dataFinal), "");
                        FacesContext.getCurrentInstance().addMessage(null, msg);              
        
        }catch(Exception e){
                        msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao gerar a Grade Horária", "");
                        FacesContext.getCurrentInstance().addMessage(null, msg);            
        }         
        
    }   
    
    
    /*
     * Método utilizado para verificar se existe grade gerada para a semana seguinte
     * Este método é chamado automaticamente todas as sextas e sábados.
     */
    public void existeGradeSemanaSeguinte(){                
        
        Calendar calendar = Calendar.getInstance(); // ou new GregorianCalendar  
        calendar.clear();  
        calendar.setTime(data);         
        
       dataInicial = grade.calculaData(data, 1);
       dataFinal   = grade.calculaData(dataInicial, 7);                  
        
        retornoGrade = consulta.consultaGrade(unidadeDao.getById(selectedUnidades),dataInicial, dataFinal);
        
        if(retornoGrade.isEmpty()){
            org.primefaces.context.RequestContext.getCurrentInstance().execute("confirmationGeraGrade.show();");  
        }
        
        unidadeCorrente = unidadeDao.getById(selectedUnidades);
        setNomeUnidade(unidadeCorrente.getNome());
        
    }    
    
    public void incluirSemanaSeguinte(){
        
        List<Turma> listaSemanaSeguinte = turmaDao.listaTurmaUnidade(selectedUnidades);
        FacesMessage msg = null;        
        LoginController usuarioLogado = new LoginController();                
        
        try{          
                 
                 dataInicial = grade.calculaData(data, 1);
                 dataFinal   = grade.calculaData(dataInicial, 7);                 
            
            for (int i = 0; i < listaSemanaSeguinte.size(); i++) {            

                 List<TurmaAula> listaAula = turmaDao.listaTurmaAula(listaSemanaSeguinte.get(i).getId());                   
                 
                 for(int j = 0; j < listaAula.size(); j++) { 

                            gradeHoraria.setTurma(turmaDao.getById(listaSemanaSeguinte.get(i).getId()));                    
                            gradeHoraria.setDisciplina(listaAula.get(j).getDisciplina());
                            gradeHoraria.setProfessor(listaAula.get(j).getProfessor());
                            gradeHoraria.setUnidade(unidadeDao.getById(selectedUnidades));
                            gradeHoraria.setHoraIni(listaAula.get(j).getHoraIni());
                            gradeHoraria.setHoraFim(listaAula.get(j).getHoraFim());
                            gradeHoraria.setTipoContrato(listaAula.get(j).getTipoContrato());
                            gradeHoraria.setSala(salaDao.getById(listaAula.get(j).getSala().getId()));
                            gradeHoraria.setMaterial(listaAula.get(j).getMaterial());
                            gradeHoraria.setData(grade.calculaData(dataInicial, listaAula.get(j).getDiaSemana().getId()));
                            gradeHoraria.setDt_cadastro(data);
                            gradeHoraria.setUsuario_cadastro(usuarioLogado.getUsuario().getId());
                            
                            retorno = gradeDao.salvar(gradeHoraria); 
                            
                                   Integer idGrade;
                                   idGrade = consulta.buscaUltRegistro();                             
                            
                                   folhaPagamento.setId_grade(idGrade);
                                   folhaPagamento.setTurma(turmaDao.getById(listaSemanaSeguinte.get(i).getId()));                    
                                   folhaPagamento.setDisciplina(listaAula.get(j).getDisciplina());
                                   folhaPagamento.setProfessor(listaAula.get(j).getProfessor());
                                   folhaPagamento.setUnidade(unidadeDao.getById(selectedUnidades));
                                   folhaPagamento.setHoraIni(listaAula.get(j).getHoraIni());
                                   folhaPagamento.setHoraIniOri(listaAula.get(j).getHoraIni());
                                   folhaPagamento.setHoraFimOri(listaAula.get(j).getHoraFim());
                                   folhaPagamento.setHoraFim(listaAula.get(j).getHoraFim());
                                   
                                    SimpleDateFormat hr = new SimpleDateFormat("HH:mm");   
                                    String pattern = "HH:mm";  

                                    DateFormat df = new SimpleDateFormat(pattern);                                     
                                    
                                    folhaPagamento.setAtraso(df.parse("00:00"));
                            
                                    Calendar calendar = Calendar.getInstance(); // ou new GregorianCalendar  
                                    calendar.clear();  
                                    calendar.setTime(grade.calculaData(data, listaAula.get(j).getDiaSemana().getId()));
                                   
                                    tipoContrato = turmaService.buscaTipoContrato(professorDao.getById(selectedProfessor), diaSemanaDao.getById(calendar.get(Calendar.DAY_OF_WEEK)), listaAula.get(j).getHoraIni(), listaAula.get(j).getHoraFim());

                                    folhaPagamento.setTipoContrato(tipoContrato);                                   
                                   
                                   folhaPagamento.setData(gradeHoraria.getData());
                                   folhaPagamento.setDt_atualizacao(data);
                                   folhaPagamento.setUsuario_atualizacao(usuarioLogado.getUsuario().getId()); 

                                    Date horaIniNova = df.parse(df.format(folhaPagamento.getHoraIni()));
                                    Date horaFimNova = df.parse(df.format(folhaPagamento.getHoraFim()));

                                    Float valor = 0F;
                                    FolhaService folhaService = new FolhaService();
                                    valor = folhaService.getValor(listaAula.get(j).getProfessor(), unidadeDao.getById(selectedUnidades), turmaDao.getById(selectedTurma), hr.parse(hr.format(horaIniNova)), hr.parse(hr.format(horaFimNova)));
                                    
                                    folhaPagamento.setValor(BigDecimal.valueOf(valor));                                   
                                   
                                   gradeDao.salvar(folhaPagamento);                            
                                   

                 }

            }
                       
                        SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy"); 
                                
                        msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Grade Horária Gerada para o Período de "+formato.format(dataInicial)+" até "+formato.format(dataFinal), "");
                        FacesContext.getCurrentInstance().addMessage(null, msg);              
        
        }catch(Exception e){
                        msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao gerar a Grade Horária", "");
                        FacesContext.getCurrentInstance().addMessage(null, msg);            
        }         
        
    }     
    
public Collection<SelectItem> getCarregarSelectProfessor() {                                      
        
        Collection<SelectItem> lst = new ArrayList<SelectItem>();        
        lst.add(new SelectItem(null, "Selecione o Professor"));      //Primeiro item do select           
        
       if(selectedDisciplina != null && selectedDisciplina != 0){
            
            listaProfessores = disciplinaDao.listaDisciplinaProfessor("p", getSelectedDisciplina());        
            
            if(!listaProfessores.isEmpty()){
                
                for(Iterator iterator = listaProfessores.get(0).getProfessores().iterator(); iterator.hasNext();){
                    
                    Professor professor = (Professor) iterator.next();                                        
                        
                        lst.add(new SelectItem(professor.getId(), professor.getNome()));              
                    
                }
                
            }
            
        }        
        
        return lst;          
    }        
    
  public Collection<SelectItem> getCarregarSelectDisciplina() {        
      
        disciplina = new Disciplina();
      
        Collection<SelectItem> lst = new ArrayList<SelectItem>();        
        lst.add(new SelectItem(null, "Selecione a Disciplina"));      //Primeiro item do select 
        
        if(getSelectedProfessor() == null || getSelectedProfessor() == 0){
            
            List<Disciplina> listaDisciplina = disciplinaDao.listaDisciplina(disciplina);

            for (int i = 0; i < listaDisciplina.size(); i++) {          
                lst.add(new SelectItem(listaDisciplina.get(i).getId(), listaDisciplina.get(i).getNome()));              
            }
            
        }else{
            
            List<Disciplina> listaDisciplina = disciplinaDao.listaDisciplinaProfessor("d", getSelectedProfessor());

            for (int i = 0; i < listaDisciplina.size(); i++) {          
                lst.add(new SelectItem(listaDisciplina.get(i).getId(), listaDisciplina.get(i).getNome()));              
            }            
            
        }
                
        return lst;          
    }
  
  public Collection<SelectItem> getCarregarSelectSala() {        
      
        sala = new Sala();
      
        Collection<SelectItem> lst = new ArrayList<SelectItem>();        
        lst.add(new SelectItem(null, "Selecione a Sala de Aula"));      //Primeiro item do select 
        
        if(selectedUnidades != null && selectedUnidades != 0){
            
            List<Sala> listaSalas = salaDao.listaSalaUnidade(sala, selectedUnidades);

            for (int i = 0; i < listaSalas.size(); i++) {          
                lst.add(new SelectItem(listaSalas.get(i).getId(), listaSalas.get(i).getPredio().getNome()+" - "+listaSalas.get(i).getNome()));              
            }
            
        }
                
        return lst;          
    }  
  
    public void preparaInclusaoAula() throws ParseException{
        
        FacesMessage msg = null;             
        
        if(selectedDisciplina == 0){
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "É necessário informar a Disciplina!", "");
                FacesContext.getCurrentInstance().addMessage(null, msg);                              
        }else if(selectedProfessor.equals("") || selectedProfessor == 0){
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "É necessário informar o Professor!", "");
                FacesContext.getCurrentInstance().addMessage(null, msg);     
        }else if(this.horaIni == null || this.horaIni.trim().equals("")){
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "É necessário informar a hora inicial!", "");
                FacesContext.getCurrentInstance().addMessage(null, msg);                     
        }else if(this.horaFim == null || this.horaFim.trim().equals("")){                        
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "É necessário informar a hora final!", "");
                FacesContext.getCurrentInstance().addMessage(null, msg); 
                
        /*
         * Tratamento para que o usuário não inclua uma data final menor ou igual a data inicial
         */        
        }else if(Integer.parseInt(this.horaFim.substring(0, 2)+this.horaFim.substring(3, 5)) <= Integer.parseInt(this.horaIni.substring(0, 2)+this.horaIni.substring(3, 5))){
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Hora Final menor ou igual a Hora Inicial", "");
                FacesContext.getCurrentInstance().addMessage(null, msg);             
        }else{
        
            if(!acao.equals("edicao")){

                    salvaAula();

            }else{
                editaAula();
                acao = "";
            }
        
        }
        
    }  
    
    public void salvaAula() throws ParseException{                
                
        FacesMessage msg = null;
        
        this.gradeHoraria.setTurma(turmaDao.getById(selectedTurma));
        this.gradeHoraria.setDisciplina(disciplinaDao.getById(selectedDisciplina));
        this.gradeHoraria.setProfessor(professorDao.getById(selectedProfessor));
        this.gradeHoraria.setUnidade(unidadeDao.getById(selectedUnidades));
                
        Calendar calendar4 = Calendar.getInstance(); // ou new GregorianCalendar  
        calendar4.clear();  
        calendar4.set(Calendar.YEAR,Integer.parseInt(this.dataAula.substring(6, 10)));
        calendar4.set(Calendar.MONTH, Integer.parseInt(this.dataAula.substring(3, 5)) - 1);
        calendar4.set(Calendar.DAY_OF_MONTH,Integer.parseInt(this.dataAula.substring(0, 2)));              
                
        this.gradeHoraria.setData(calendar4.getTime());        
        
        Calendar calendar = Calendar.getInstance(); // ou new GregorianCalendar  
        calendar.clear();  
        calendar.set(Integer.parseInt(this.dataAula.substring(7, 10)), Integer.parseInt(this.dataAula.substring(3, 5)), Integer.parseInt(this.dataAula.substring(0, 1)));
        calendar.setTime(data);   
                
        calendar.set(Calendar.HOUR_OF_DAY,Integer.parseInt(horaIni.substring(0, 2)));        
        calendar.set(Calendar.MINUTE,Integer.parseInt(horaIni.substring(3, 5)));
        calendar.set(Calendar.SECOND,0);
                
        this.gradeHoraria.setHoraIni(calendar.getTime());        
        
        Date dataAtual2 = new Date();
        Calendar calendar2 = Calendar.getInstance();  
        
        calendar2.setTime(dataAtual2);    
        calendar2.set(Calendar.HOUR_OF_DAY,Integer.parseInt(horaFim.substring(0,2)));
        calendar2.set(Calendar.MINUTE,Integer.parseInt(horaFim.substring(3, 5)));
        calendar2.set(Calendar.SECOND,0);
        
        this.gradeHoraria.setHoraFim(calendar2.getTime());      
        
        this.gradeHoraria.setSala(salaDao.getById(selectedSala));
        
        this.gradeHoraria.setMaterial(selectedMaterial);

        //Seta a data de Cadastro
        this.gradeHoraria.setDt_cadastro(data);
        
        LoginController usuarioLogado = new LoginController();

        SimpleDateFormat hr = new SimpleDateFormat("HH:mm");   
        String pattern = "HH:mm";  
        
        DateFormat df = new SimpleDateFormat(pattern);                  
        
        //Seta usuário que cadastrou a aula
        this.gradeHoraria.setUsuario_cadastro(usuarioLogado.Usuario.getId()); 
        
        /*
         * É realizada a validação afim de saber se aula selecionada para ser editada já ocorreu
         * Caso já tenha ocorrido não é permitida a edição
         */
        if(grade.validaAula(gradeHoraria.getData(), data, gradeHoraria.getHoraFim())){

            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Não será permitida a inclusão de uma aula já realizada!", "");
            FacesContext.getCurrentInstance().addMessage(null, msg);                                       
            
        }else{
            
            Long retornoAulaProfessor;
            Long retornoAulaTurma;
                       
            retornoAulaProfessor = consulta.consultaAulaProfessor(professorDao.getById(selectedProfessor), calendar4.getTime(),calendar.getTime(),calendar2.getTime());
            
            retornoAulaTurma = consulta.consultaAulaTurma(turmaDao.getById(selectedTurma), calendar4.getTime(),calendar.getTime(),calendar2.getTime());
            
            if(retornoAulaProfessor != 0 || retornoAulaTurma != 0){
                    msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Professor/Turma já possui aula no mesmo dia e horário", "");
                    FacesContext.getCurrentInstance().addMessage(null, msg);                 
            }else{
        
                retorno = gradeDao.salvar(this.gradeHoraria);
                
                Integer idGrade;
                idGrade = consulta.buscaUltRegistro();        
                        
                folhaPagamento.setId_grade(idGrade);
                folhaPagamento.setTurma(turmaDao.getById(selectedTurma));
                folhaPagamento.setDisciplina(disciplinaDao.getById(selectedDisciplina));
                folhaPagamento.setProfessor(professorDao.getById(selectedProfessor));
                folhaPagamento.setUnidade(unidadeDao.getById(selectedUnidades));
                folhaPagamento.setHoraIni(calendar.getTime());
                folhaPagamento.setHoraIniOri(calendar.getTime());
                folhaPagamento.setHoraFimOri(calendar2.getTime());
                folhaPagamento.setHoraFim(calendar2.getTime());
                folhaPagamento.setAtraso(df.parse("00:00"));
        
                tipoContrato = turmaService.buscaTipoContrato(professorDao.getById(selectedProfessor), diaSemanaDao.getById(calendar2.get(Calendar.DAY_OF_WEEK)), calendar.getTime(), calendar2.getTime());
        
                folhaPagamento.setTipoContrato(tipoContrato);
        
                folhaPagamento.setData(this.gradeHoraria.getData());
                folhaPagamento.setDt_atualizacao(data);
                folhaPagamento.setUsuario_atualizacao(usuarioLogado.Usuario.getId()); 
        
                Date horaIniNova = df.parse(df.format(folhaPagamento.getHoraIni()));
                Date horaFimNova = df.parse(df.format(folhaPagamento.getHoraFim()));
        
                Float valor = 0F;
                FolhaService folhaService = new FolhaService();
                valor = folhaService.getValor(folhaPagamento.getProfessor(), folhaPagamento.getUnidade(), folhaPagamento.getTurma(), hr.parse(hr.format(horaIniNova)), hr.parse(hr.format(horaFimNova)));
                System.out.println("******Valor*******"+valor);
                folhaPagamento.setValor(BigDecimal.valueOf(valor));        
        
                teste = gradeDao.salvar(folhaPagamento);               

                resetGrade();                

                        Calendar calendar3 = Calendar.getInstance(); // ou new GregorianCalendar  
                        calendar3.clear();  
                        calendar3.setTime(data);         

                        dataInicial = grade.calculaData(data, calendar3.get(Calendar.DAY_OF_WEEK));
                        dataFinal   = grade.calculaData(data, 7);             

                        lista = new ListDataModel(consulta.consultaGrade(unidadeDao.getById(selectedUnidades),dataInicial, dataFinal));                                

                    if(retorno){                   
                        msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Aula cadastrada com sucesso!", "");
                        FacesContext.getCurrentInstance().addMessage(null, msg);
                    }else{
                        msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Falha ao cadastrar Aula!", "");
                        FacesContext.getCurrentInstance().addMessage(null, msg);            
                    }   
                    
            }
        
        }
        
    }        
  
    public void preparaEdicao() throws ParseException{
        FacesMessage msg = null;        
        if(filtroSelecionado == 1){
            atualizaLista();
        }        
        
        /*
         * É realizada a validação afim de saber se aula selecionada para ser editada já ocorreu
         * Caso já tenha ocorrido não é permitida a edição
         */
        if(grade.validaAula(gradeHorariaSelecionada.getData(), data, gradeHorariaSelecionada.getHoraFim())){

            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Aula já realizada, não será permitida a edição!", "");
            FacesContext.getCurrentInstance().addMessage(null, msg);            
            
        }else{
                
            this.gradeHoraria       = gradeHorariaSelecionada;
            
            this.folhaPagamento     = calculoDao.getByIdGrade(this.gradeHoraria.getId());
            
            this.selectedDisciplina = this.gradeHorariaSelecionada.getDisciplina().getId();
            this.selectedProfessor  = this.gradeHorariaSelecionada.getProfessor().getId();
            this.selectedTurma      = this.gradeHorariaSelecionada.getTurma().getId();
            
            this.selectedSala       = this.gradeHorariaSelecionada.getSala().getId();
            
            this.selectedMaterial   = this.gradeHorariaSelecionada.getMaterial();

            //Tratamento para preencher com zeros a esquerda
            this.horaIni = this.horaIni.format("%02d", this.gradeHorariaSelecionada.getHoraIni().getHours()) + ":" + this.getHoraIni().format("%02d", this.gradeHorariaSelecionada.getHoraIni().getMinutes());
            this.horaFim = this.horaFim.format("%02d", this.gradeHorariaSelecionada.getHoraFim().getHours()) + ":" + this.getHoraFim().format("%02d", this.gradeHorariaSelecionada.getHoraFim().getMinutes());

            SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy"); 

            this.dataAula = formato.format(this.gradeHorariaSelecionada.getData());                

            Calendar calendar = Calendar.getInstance(); // ou new GregorianCalendar  
            calendar.clear();  
            calendar.set(Calendar.YEAR,Integer.parseInt(this.dataAula.substring(6, 10)));
            calendar.set(Calendar.MONTH, Integer.parseInt(this.dataAula.substring(3, 5)) - 1);
            calendar.set(Calendar.DAY_OF_MONTH,Integer.parseInt(this.dataAula.substring(0, 2)));              

            this.gradeHoraria.setData(calendar.getTime());                        

            acao = "edicao";
        
        }
    }
    
    public void editaAula() throws ParseException{
        
        FacesMessage msg = null;    
        
        Calendar calendar4 = Calendar.getInstance(); // ou new GregorianCalendar  
        calendar4.clear();  
        calendar4.set(Calendar.YEAR,Integer.parseInt(this.dataAula.substring(6, 10)));
        calendar4.set(Calendar.MONTH, Integer.parseInt(this.dataAula.substring(3, 5)) - 1);
        calendar4.set(Calendar.DAY_OF_MONTH,Integer.parseInt(this.dataAula.substring(0, 2)));              
                
        this.gradeHoraria.setData(calendar4.getTime());        
        
        Calendar calendar = Calendar.getInstance(); // ou new GregorianCalendar  
        calendar.clear();  
        calendar.set(Integer.parseInt(this.dataAula.substring(7, 10)), Integer.parseInt(this.dataAula.substring(3, 5)), Integer.parseInt(this.dataAula.substring(0, 1)));
        calendar.setTime(data);   
                
        calendar.set(Calendar.HOUR_OF_DAY,Integer.parseInt(horaIni.substring(0, 2)));        
        calendar.set(Calendar.MINUTE,Integer.parseInt(horaIni.substring(3, 5)));
        calendar.set(Calendar.SECOND,0);
                
        this.gradeHoraria.setHoraIni(calendar.getTime());        
        
        Date dataAtual2 = new Date();
        Calendar calendar2 = Calendar.getInstance();  
        
        calendar2.setTime(dataAtual2);    
        calendar2.set(Calendar.HOUR_OF_DAY,Integer.parseInt(horaFim.substring(0,2)));
        calendar2.set(Calendar.MINUTE,Integer.parseInt(horaFim.substring(3, 5)));
        calendar2.set(Calendar.SECOND,0);
        
        this.gradeHoraria.setHoraFim(calendar2.getTime());         
        
        this.gradeHoraria.setTurma(turmaDao.getById(selectedTurma));
        this.gradeHoraria.setDisciplina(disciplinaDao.getById(selectedDisciplina));
        this.gradeHoraria.setProfessor(professorDao.getById(selectedProfessor));
        this.gradeHoraria.setUnidade(unidadeDao.getById(selectedUnidades));  
        this.gradeHoraria.setSala(salaDao.getById(selectedSala));
                        
        //Seta data de atualização
        gradeHoraria.setDt_atualizacao(data);
        
        LoginController usuarioLogado = new LoginController();
        
        //Seta usuário que está alterando o professor
        gradeHoraria.setUsuario_atualizacao(usuarioLogado.Usuario.getId());  
        
        
        if(grade.validaAula(calendar4.getTime(), data, calendar2.getTime())){

                    msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Não será permitida a inclusão de uma aula já realizada!", "");
                    FacesContext.getCurrentInstance().addMessage(null, msg);     
                    
        }else{
        
                retorno = gradeDao.atualizar(gradeHoraria);
                
                SimpleDateFormat hr = new SimpleDateFormat("HH:mm");   
                String pattern = "HH:mm";  

                DateFormat df = new SimpleDateFormat(pattern);                 
                
                folhaPagamento.setId_grade(gradeHoraria.getId());
                folhaPagamento.setTurma(turmaDao.getById(selectedTurma));
                folhaPagamento.setDisciplina(disciplinaDao.getById(selectedDisciplina));
                folhaPagamento.setProfessor(professorDao.getById(selectedProfessor));
                folhaPagamento.setUnidade(unidadeDao.getById(selectedUnidades));
                folhaPagamento.setHoraIni(this.gradeHoraria.getHoraIni());
                folhaPagamento.setHoraIniOri(this.gradeHoraria.getHoraIni());
                folhaPagamento.setHoraFimOri(this.gradeHoraria.getHoraFim());
                folhaPagamento.setHoraFim(this.gradeHoraria.getHoraFim());
                folhaPagamento.setAtraso(df.parse("00:00"));
        
                tipoContrato = turmaService.buscaTipoContrato(professorDao.getById(selectedProfessor), diaSemanaDao.getById(calendar2.get(Calendar.DAY_OF_WEEK)), calendar.getTime(), calendar2.getTime());
        
                folhaPagamento.setTipoContrato(tipoContrato);
        
                folhaPagamento.setData(this.gradeHoraria.getData());
                folhaPagamento.setDt_atualizacao(data);
                folhaPagamento.setUsuario_atualizacao(usuarioLogado.Usuario.getId()); 
        
                Date horaIniNova = df.parse(df.format(folhaPagamento.getHoraIni()));
                Date horaFimNova = df.parse(df.format(folhaPagamento.getHoraFim()));
        
                Float valor = 0F;
                FolhaService folhaService = new FolhaService();
                valor = folhaService.getValor(folhaPagamento.getProfessor(), folhaPagamento.getUnidade(), folhaPagamento.getTurma(), hr.parse(hr.format(horaIniNova)), hr.parse(hr.format(horaFimNova)));
                
                folhaPagamento.setValor(BigDecimal.valueOf(valor));        
        
                teste = gradeDao.atualizar(folhaPagamento);                

                resetGrade();

                lista = new ListDataModel(consulta.consultaGrade(unidadeDao.getById(selectedUnidades),dataInicial, dataFinal));         

                if(retorno){           

                    msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Grade atualizada com sucesso!", "");
                    FacesContext.getCurrentInstance().addMessage(null, msg);

                } 
        
        }
        
    }
    
    public void deleteAula(){
        
            FacesMessage msg = null;  
            
            if(this.gradeHorariaSelecionada == null){
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Selecione uma Aula para ser deletada!", "");
                FacesContext.getCurrentInstance().addMessage(null, msg);                
            }else{
                gradeDao.excluir(this.gradeHorariaSelecionada);
                
                folhaPagamento = calculoDao.getByIdGrade(this.gradeHorariaSelecionada.getId());                
                gradeDao.excluir(folhaPagamento);
                
                resetGrade();
                
                Calendar calendar = Calendar.getInstance(); // ou new GregorianCalendar  
                calendar.clear();  
                calendar.setTime(data);         

                dataInicial = grade.calculaData(data, calendar.get(Calendar.DAY_OF_WEEK));
                dataFinal   = grade.calculaData(data, 7);             

                    lista = new ListDataModel(consulta.consultaGrade(unidadeDao.getById(selectedUnidades),dataInicial, dataFinal));                
                
            }        
        
    }
    
    public void resetGrade(){
        
        gradeHoraria = new GradeHoraria();        
                
        this.horaFim      = "";
        this.horaIni      = "";
        this.dataAula     = "";
        this.selectedDisciplina = 0;
        this.selectedProfessor  = 0;
        this.selectedTurma      = 0;
        this.selectedSala       = 0;
        this.selectedMaterial   = "";
        acao = "";
        
    }
    
    /*
     * Geração do relatorio
     */
    
    public void sampleReportPDF() throws IOException{    

    try {        
        
        InputStream relatorio = getClass().getResourceAsStream("../relatorios/folhaPonto.jasper");
        System.out.println("Relatorio :"+relatorio);
        HashMap<String, Integer> params = new HashMap<String, Integer>();
        
        List<Object> listGrade = new ArrayList<Object>();                
                
        listGrade = consulta.listaGradePf(unidadeCorrente);
        
        JRDataSource jrds = new JRBeanCollectionDataSource(listGrade);
        
        JasperPrint print = JasperFillManager.fillReport(relatorio,new HashMap(), jrds);
         
        byte[] bytes = JasperExportManager.exportReportToPdf(print);        
        
        JasperViewer.viewReport(print, false);                     

     } catch (JRException ex) {
         Logger.getLogger(ex.getMessage()).log(Level.SEVERE, null, ex);
         System.out.println("Erro relatório :"+ex.getMessage());
     }
     

    }    

    public GradeHoraria getGradeHoraria() {
        return gradeHoraria;
    }

    public void setGradeHoraria(GradeHoraria gradeHoraria) {
        this.gradeHoraria = gradeHoraria;
    }

    public Integer getSelectedUnidades() {
        return selectedUnidades;
    }

    public void setSelectedUnidades(Integer selectedUnidades) {
        this.selectedUnidades = selectedUnidades;
    }

    public String getNomeUnidade() {
        return nomeUnidade;
    }

    public void setNomeUnidade(String nomeUnidade) {
        this.nomeUnidade = nomeUnidade;
    }

    public DataModel getLista() {
        
       if(lista == null || lista.getRowCount() == 0){

                Calendar calendar = Calendar.getInstance(); // ou new GregorianCalendar  
                calendar.clear();  
                calendar.setTime(data);         

                dataInicial = grade.calculaDataAnterior(data, 1);
                dataFinal   = grade.calculaData(data, 7);                               

                    lista = new ListDataModel(consulta.consultaGrade(unidadeDao.getById(selectedUnidades),dataInicial, dataFinal));                    

        }        
        
       
        if(filtroSelecionado == 1 && dataIniFiltro != null){
            lista = null;
            atualizaLista();
        }
                       
        return lista;
    }

    public void setLista(DataModel lista) {
        this.lista = lista;
    }

    public GradeHoraria getGradeHorariaSelecionada() {
        return gradeHorariaSelecionada;
    }

    public void setGradeHorariaSelecionada(GradeHoraria gradeHorariaSelecionada) {
        this.gradeHorariaSelecionada = gradeHorariaSelecionada;
    }

    public Integer getSelectedDisciplina() {
        return selectedDisciplina;
    }

    public void setSelectedDisciplina(Integer selectedDisciplina) {
        this.selectedDisciplina = selectedDisciplina;
    }

    public Integer getSelectedProfessor() {
        return selectedProfessor;
    }

    public void setSelectedProfessor(Integer selectedProfessor) {
        this.selectedProfessor = selectedProfessor;
    }

    public String getHoraIni() {
        return horaIni;
    }

    public void setHoraIni(String horaIni) {
        this.horaIni = horaIni;
    }

    public String getHoraFim() {
        return horaFim;
    }

    public void setHoraFim(String horaFim) {
        this.horaFim = horaFim;
    }

    public String getDataAula() {
        return dataAula;
    }

    public void setDataAula(String dataAula) {
        this.dataAula = dataAula;
    }

    public Turma getTurma() {
        return turma;
    }

    public void setTurma(Turma turma) {
        this.turma = turma;
    }

    public Integer getSelectedTurma() {
        return selectedTurma;
    }


    public void setSelectedTurma(Integer selectedTurma) {
        this.selectedTurma = selectedTurma;
    }

    public Integer getFiltroSelecionado() {
        return filtroSelecionado;
    }

    public void setFiltroSelecionado(Integer filtroSelecionado) {
        this.filtroSelecionado = filtroSelecionado;
    }

    public Boolean getExibeDatas() {
        if(filtroSelecionado == 0){
            exibeDatas = false;
            lista = null;
            getLista();
            dataIniFiltro = "";
            dataFimFiltro = "";
        }else{
            exibeDatas = true;
        }
        return exibeDatas;
    }

    public void setExibeDatas(Boolean exibeDatas) {
        this.exibeDatas = exibeDatas;
    }

    public String getDataIniFiltro() {
        return dataIniFiltro;
    }


    public void setDataIniFiltro(String dataIniFiltro) {
        this.dataIniFiltro = dataIniFiltro;
    }

    public String getDataFimFiltro() {
        return dataFimFiltro;
    }

    public void setDataFimFiltro(String dataFimFiltro) {
        this.dataFimFiltro = dataFimFiltro;
    }

    /**
     * @return the selectedSala
     */
    public Integer getSelectedSala() {
        return selectedSala;
    }

    /**
     * @param selectedSala the selectedSala to set
     */
    public void setSelectedSala(Integer selectedSala) {
        this.selectedSala = selectedSala;
    }

    /**
     * @return the selectedMaterial
     */
    public String getSelectedMaterial() {
        return selectedMaterial;
    }

    /**
     * @param selectedMaterial the selectedMaterial to set
     */
    public void setSelectedMaterial(String selectedMaterial) {
        this.selectedMaterial = selectedMaterial;
    }
    
}